//! DECRBY命令修复功能单元测试
//! 
//! 测试修复后的DECR/DECRBY命令功能，包括：
//! - DECR命令的正确实现
//! - DECRBY命令的参数解析和错误处理
//! - 数值格式验证和错误响应
//! - 边界情况处理（溢出、非数字值等）
//! - 不存在键的默认值行为

use std::collections::HashMap;

/// 模拟简化版存储，用于测试数值操作
#[derive(Debug, Default)]
struct MockStorage {
    data: HashMap<String, String>,
}

/// DECRBY命令的结果类型
#[derive(Debug, PartialEq)]
enum DecrbyResult {
    Success(i64),
    Error(String),
}

impl MockStorage {
    fn new() -> Self {
        Self {
            data: HashMap::new(),
        }
    }
    
    /// 实现修复后的DECR逻辑
    fn decr(&mut self, key: &str) -> i64 {
        let current = self.data.get(key)
            .and_then(|v| v.parse::<i64>().ok())
            .unwrap_or(0);
        let new_value = current - 1;
        self.data.insert(key.to_string(), new_value.to_string());
        new_value
    }
    
    /// 实现修复后的DECRBY逻辑（带错误处理）
    fn decrby(&mut self, key: &str, decrement_str: &str) -> DecrbyResult {
        // 正确解析递减值，如果解析失败返回错误
        match decrement_str.parse::<i64>() {
            Ok(decrement) => {
                let current = self.data.get(key)
                    .and_then(|v| v.parse::<i64>().ok())
                    .unwrap_or(0);
                
                // 检查溢出
                match current.checked_sub(decrement) {
                    Some(new_value) => {
                        self.data.insert(key.to_string(), new_value.to_string());
                        DecrbyResult::Success(new_value)
                    }
                    None => {
                        DecrbyResult::Error("integer overflow".to_string())
                    }
                }
            }
            Err(_) => {
                DecrbyResult::Error("value is not an integer or out of range".to_string())
            }
        }
    }
    
    /// 设置字符串值
    fn set(&mut self, key: &str, value: &str) {
        self.data.insert(key.to_string(), value.to_string());
    }
    
    /// 获取字符串值
    fn get(&self, key: &str) -> Option<String> {
        self.data.get(key).cloned()
    }
}

#[cfg(test)]
mod decr_tests {
    use super::*;
    
    #[test]
    fn test_decr_nonexistent_key() {
        let mut storage = MockStorage::new();
        
        // 对不存在的键执行DECR，应该从0开始递减
        let result = storage.decr("counter");
        assert_eq!(result, -1, "不存在的键应该从0开始递减到-1");
        
        // 验证键已创建
        assert_eq!(storage.get("counter"), Some("-1".to_string()));
    }
    
    #[test]
    fn test_decr_existing_key() {
        let mut storage = MockStorage::new();
        
        // 设置初始值
        storage.set("counter", "10");
        
        // 执行DECR
        let result = storage.decr("counter");
        assert_eq!(result, 9, "现有键应该正确递减");
        
        // 验证值已更新
        assert_eq!(storage.get("counter"), Some("9".to_string()));
    }
    
    #[test]
    fn test_decr_zero_value() {
        let mut storage = MockStorage::new();
        
        // 设置零值
        storage.set("counter", "0");
        
        // 执行DECR
        let result = storage.decr("counter");
        assert_eq!(result, -1, "零值应该递减到-1");
    }
}

#[cfg(test)]
mod decrby_tests {
    use super::*;
    
    #[test]
    fn test_decrby_valid_positive_decrement() {
        let mut storage = MockStorage::new();
        
        // 设置初始值
        storage.set("counter", "10");
        
        // 执行DECRBY
        let result = storage.decrby("counter", "3");
        assert_eq!(result, DecrbyResult::Success(7), "应该正确递减3");
        
        // 验证值已更新
        assert_eq!(storage.get("counter"), Some("7".to_string()));
    }
    
    #[test]
    fn test_decrby_invalid_decrement_not_number() {
        let mut storage = MockStorage::new();
        
        // 使用非数字递减值
        let result = storage.decrby("counter", "not_a_number");
        assert_eq!(
            result,
            DecrbyResult::Error("value is not an integer or out of range".to_string()),
            "非数字递减值应该返回错误"
        );
        
        // 验证原键未被修改
        assert_eq!(storage.get("counter"), None);
    }
}